package com.trover.core.http

import android.util.Log
import com.google.gson.JsonParseException
import com.trover.core.http.apimodel.Result
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import okhttp3.ResponseBody
import org.json.JSONException
import retrofit2.HttpException
import java.io.IOException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.text.ParseException

open class BaseRepository {

    suspend fun <T : Any> apiCall(call: suspend () -> T): T {
        return call.invoke()
    }

    suspend fun <T : Any> safeApiCall(call: suspend () -> Result<T>, errorMsg: String): Result<T> {
        return try {
            call()
        } catch (e: Throwable) {
            executeHttpException(e)
        }
    }

    private fun <T : Any> executeHttpException(e: Throwable): Result<T> {
        e.printStackTrace()
        if (e is HttpException) {
            val body: ResponseBody? = e.response()?.errorBody()
            Log.e("httpError ", "errCode=> ${e.code()} body=> ${body?.string()}")
            when (e.code()) {
                BaseApiService.ACCESS_TOKEN_EXPIRED, BaseApiService.UNAUTHORIZED,
                BaseApiService.SUCCESS_NO_RESPONSE -> {
                    return Result.Error.NoResponseError(IOException("登录状态失效，请重新登录"))
                }
                BaseApiService.BAD_REQUEST -> {
                    return Result.Error.RecoverableError(IOException("请求参数有误，请重试"))
                }
                BaseApiService.BAD_GATEWAY,
                BaseApiService.CONFLICT, BaseApiService.FORBIDDEN, BaseApiService.GATEWAY_TIMEOUT,
                BaseApiService.INTERNAL_SERVER_ERROR, BaseApiService.METHOD_NOT_ALLOWED,
                BaseApiService.NOT_FOUND, BaseApiService.PRECONDITION_FAILED, BaseApiService.REQUEST_TIMEOUT,
                BaseApiService.SERVICE_UNAVAILABLE -> {
                    return Result.Error.RecoverableError(IOException("请求失败，请稍后重试"))
                }
                else -> return Result.Error.RecoverableError(IOException("请求失败，请稍后重试~"))
            }
        } else {
            val errorMsg = if (e is UnknownHostException) {
                "网络异常"
            } else if (e is JSONException || e is JsonParseException) {
                "数据异常"
            } else if (e is SocketTimeoutException) {
                "连接超时"
            } else if (e is ConnectException) {
                "连接错误"
            } else if (e is BusinessHttpException) {
                e.businessMessage
            } else if (e is JSONException || e is JsonParseException || e is ParseException) {
                "解析错误"
            } else {
                "未知错误"
            }
            return Result.Error.NonRecoverableError(IOException(errorMsg))
        }
    }


    suspend fun <T : Any> executeResponse(
        response: BaseResponse<T>, successBlock: (suspend CoroutineScope.() -> Unit)? = null,
        errorBlock: (suspend CoroutineScope.() -> Unit)? = null
    ): Result<T> {
        return coroutineScope {
            if (response.errorCode == -1) {
                errorBlock?.let { it() }
                Result.Error.RecoverableError(IOException(response.errorMessage))
            } else {
                successBlock?.let { it() }
                Result.Success(response.data)
            }
        }
    }
}